package com.sc.admin.core.api.web;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sc.admin.core.bo.MenuBo;
import com.sc.admin.core.bo.OrganizationBo;
import com.sc.admin.core.service.*;
import com.sc.admin.core.service.*;
import com.sc.common.annotations.OperationLog;
import com.sc.common.annotations.WebApi;
import com.sc.common.context.DefaultBusinessContext;
import com.sc.common.dto.WebResponseDto;
import com.sc.common.entity.admin.account.SysAccount;
import com.sc.common.entity.admin.lookup.SysLookup;
import com.sc.common.entity.admin.menu.SysMenu;
import com.sc.common.entity.admin.user.SysUser;
import com.sc.common.entity.admin.user.SysUserList;
import com.sc.common.entity.admin.userorganization.SysUserOrganization;
import com.sc.common.enums.ApplicationEnum;
import com.sc.common.enums.OperationLogEnum;
import com.sc.common.util.RC4;
import com.sc.common.util.cache.DataDictionaryUtil;
import com.sc.common.util.cache.SpringRedisTools;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.*;


/**
 * @author ：wust
 * @date ：Created in 2019/9/4 15:41
 * @description：
 * @version:
 */
@WebApi
@RequestMapping("/web/v1/IndexController")
@RestController
public class IndexController {
    @Autowired
    private SpringRedisTools springRedisTools;

    @Autowired
    private SysUserService sysUserServiceImpl;

    @Autowired
    private SysMenuService sysMenuServiceImpl;

    @Autowired
    private SysUserOrganizationService sysUserOrganizationServiceImpl;

    @Autowired
    private SysAccountService sysAccountServiceImpl;

    @Autowired
    private SysMyNoticeService sysMyNoticeServiceImpl;

    @Autowired
    private MenuBo menuBo;

    @Autowired
    private SysOrganizationService sysOrganizationServiceImpl;

    @Autowired
    private SysDepartmentService sysDepartmentServiceImpl;

    @Autowired
    private SysCompanyService sysCompanyServiceImpl;

    @Autowired
    private SysProjectService sysProjectServiceImpl;

    @Autowired
    private SysRoleService sysRoleServiceImpl;

    @Autowired
    private OrganizationBo organizationBo;


    /**
     * 切换项目，将当前选中的项目和项目所属的公司绑定给当前用户，并放入缓存
     * @param projectId
     * @return
     */
    @RequestMapping(value = "/switchProject/{projectId}",method = RequestMethod.POST)
    public WebResponseDto switchProject(@PathVariable Long projectId){
        WebResponseDto responseDto = new WebResponseDto();
        DefaultBusinessContext ctx = DefaultBusinessContext.getContext();

        String key = ctx.getRedisKey();
        Map map = springRedisTools.getMap(key);
        if(map != null){
            SysUserOrganization search = new SysUserOrganization();
            search.setProjectId(projectId);
            List<SysUserOrganization> userOrganizations = sysUserOrganizationServiceImpl.select(search);
            if(CollectionUtil.isNotEmpty(userOrganizations)){
                SysUserOrganization sysUserOrganization = userOrganizations.get(0);
                springRedisTools.addFieldToMap(key,"companyId",sysUserOrganization.getBranchCompanyId());
                springRedisTools.addFieldToMap(key,"agentId",sysUserOrganization.getAgentId());
            }
            springRedisTools.addFieldToMap(key,"projectId",projectId);
        }else{
            responseDto.setFlag(WebResponseDto.INFO_WARNING);
            responseDto.setMessage("请先登录系统");
        }
        return responseDto;
    }


    /**
     * 修改登录密码
     * @param passwordOld
     * @param passwordNew
     * @param passwordNewAgain
     * @return
     */
    @OperationLog(moduleName= OperationLogEnum.MODULE_ADMIN_SETTING,businessName="修改密码",operationType= OperationLogEnum.Update)
    @RequestMapping(value = "/changePassword",method = RequestMethod.POST)
    public WebResponseDto changePassword(@RequestParam String passwordOld, @RequestParam String passwordNew, @RequestParam String passwordNewAgain){
        WebResponseDto responseDto = new WebResponseDto();
        DefaultBusinessContext ctx = DefaultBusinessContext.getContext();

        if(!passwordNew.equals(passwordNewAgain)){
            responseDto.setFlag(WebResponseDto.INFO_WARNING);
            responseDto.setMessage("两次密码不一致");
            return responseDto;
        }


        String passwordOldRC4 = RC4.encry_RC4_string(passwordOld,ApplicationEnum.LOGIN_RC4_KEY.getStringValue());
        SysAccount accountSearch = new SysAccount();
        accountSearch.setAccountCode(ctx.getAccountCode());
        accountSearch.setPassword(passwordOldRC4);
        SysAccount account = sysAccountServiceImpl.selectOne(accountSearch);
        if(account == null){
            responseDto.setFlag(WebResponseDto.INFO_WARNING);
            responseDto.setMessage("旧密码输入有误");
            return responseDto;
        }

        String passwordNewRC4 = RC4.encry_RC4_string(passwordNew,ApplicationEnum.LOGIN_RC4_KEY.getStringValue());
        SysAccount accountUpdate = new SysAccount();
        accountUpdate.setId(ctx.getAccountId());
        accountUpdate.setPassword(passwordNewRC4);
        sysAccountServiceImpl.updateByPrimaryKeySelective(accountUpdate);
        return responseDto;
    }




    /**
     * 根据根菜单构建所有子菜单数据
     * @param pcode
     * @return
     */
    @RequestMapping(value = "/buildAsideMenuJson",method = RequestMethod.POST)
    public WebResponseDto buildAsideMenuJson(@RequestParam("pcode") String pcode){
        WebResponseDto responseDto = new WebResponseDto();
        DefaultBusinessContext ctx = DefaultBusinessContext.getContext();
        List<SysMenu> menus = null;
        if(ctx.isSuperAdmin()){
            menus = sysMenuServiceImpl.findAsideMenu4superAdmin(ctx.getPermissionType(),ctx.getLocale().toString());
        }else if(ctx.isAdmin()){
            menus = sysMenuServiceImpl.findAsideMenu4admin(ctx.getPermissionType(),ctx.getLocale().toString(),ctx.getAccountId());
        }else if(ctx.isStaff()){
            menus = sysMenuServiceImpl.findAsideMenuByUserId(ctx.getPermissionType(),ctx.getLocale().toString(),ctx.getAccountId());
        }else{
            responseDto.setFlag(WebResponseDto.INFO_WARNING);
            responseDto.setMessage("非法到用户");
            return responseDto;
        }

        if(CollectionUtils.isNotEmpty(menus)){
            Map<String,List<SysMenu>> groupMenusByPcodeMap = menuBo.groupMenusByPcode(menus);
            final JSONArray jsonArray = new JSONArray(20);

            if(groupMenusByPcodeMap.containsKey(pcode)) {
                List<SysMenu> children = groupMenusByPcodeMap.get(pcode);
                if (CollectionUtils.isNotEmpty(children)) {
                    for (SysMenu child : children) {
                        JSONObject jsonObject = (JSONObject) JSONObject.toJSON(child);
                        jsonObject.put("children",new JSONArray(0));
                        jsonArray.add(jsonObject);

                        menuBo.lookupAllChildrenMenu(groupMenusByPcodeMap,jsonArray);
                    }

                }
            }
            menuBo.lookupAllChildrenMenu(groupMenusByPcodeMap,jsonArray);
            responseDto.setObj(jsonArray);
        }
        return responseDto;
    }



    /**
     * 获取当前登录账号的未读消息数量
     * @return
     */
    @RequestMapping(value = "/getUnreadNoticeCount",method = RequestMethod.GET)
    public WebResponseDto getUnreadNoticeCount(){
        WebResponseDto responseDto = new WebResponseDto();
        DefaultBusinessContext ctx = DefaultBusinessContext.getContext();

        List<SysLookup> lookups = DataDictionaryUtil.getLookupListByParentCode(ctx.getLocale().toString(),"A1021");

        JSONObject jsonObject = new JSONObject();
        for (SysLookup lookup : lookups) {
            jsonObject.put(lookup.getCode(),0);
        }

        List<Map> maps = sysMyNoticeServiceImpl.getUnreadNoticeCount("A101502",ctx.getAccountId().toString());
        if(CollectionUtils.isNotEmpty(maps)){
            for (Map map : maps) {
                if(CollectionUtil.isEmpty(map)){
                    continue;
                }
                jsonObject.put(Convert.toStr(map.get("notification_type")), Convert.toInt(map.get("notification_count")));
            }
        }
        responseDto.setObj(jsonObject);
        return responseDto;
    }


    /**
     * 判断当前登录账号是否为接收者范围。
     * 也就是，如果receiverType为公司类型，则receiver为公司id，那么就判断当前登录用户是否属于此公司的员工。
     * 以此类推，其他receiverType类型也是这么算的。
     * @param receiverType 接收者类型
     * @param receiver 接收者类型对应的关联id
     * @return
     */
    @RequestMapping(value = {"/isMyNotice/{receiverType}/{receiver}","/isMyNotice/{receiverType}"},method = RequestMethod.GET)
    public WebResponseDto isMyNotice(@PathVariable String receiverType, @PathVariable(required = false) String receiver){
        WebResponseDto responseDto = new WebResponseDto();
        DefaultBusinessContext ctx = DefaultBusinessContext.getContext();
        boolean result = false;
        SysUserOrganization sysUserOrganizationSearch = new SysUserOrganization();
        sysUserOrganizationSearch.setUserId(ctx.getAccountId());
        if("A101401".equals(receiverType)) { // 当前系统所有用户，不包括系统管理员
            if(ctx.isSuperAdmin()){
                result = false;
            }else{
                result = true;
            }
        }else{
            if("A101402".equals(receiverType)) { // 公司用户
                sysUserOrganizationSearch.setBranchCompanyId(Long.valueOf(receiver));
            }else if("A101403".equals(receiverType)) { // 项目用户
                sysUserOrganizationSearch.setProjectId(Long.valueOf(receiver));
            }else if("A101404".equals(receiverType)) { // 部门用户
                sysUserOrganizationSearch.setDepartmentId(Long.valueOf(receiver));
            }else if("A101404".equals(receiverType)) { // 角色用户
                sysUserOrganizationSearch.setRoleId(Long.valueOf(receiver));
            }

            List<SysUserOrganization> sysUserOrganizations =  sysUserOrganizationServiceImpl.select(sysUserOrganizationSearch);
            if(CollectionUtils.isNotEmpty(sysUserOrganizations)){
                result = true;
            }
        }

        responseDto.setObj(result);
        return responseDto;
    }



    @RequestMapping(value = {"/getLoginUserDetail"},method = RequestMethod.GET)
    public WebResponseDto getLoginUserDetail(){
        WebResponseDto responseDto = new WebResponseDto();
        DefaultBusinessContext ctx = DefaultBusinessContext.getContext();

        SysUser user = sysUserServiceImpl.selectByPrimaryKey(ctx.getAccountId());
        SysUserList userList = new SysUserList();
        BeanUtil.copyProperties(user,userList);

        responseDto.setObj(userList);
        return responseDto;
    }


    /**
     * 获取登录用户的组织结构
     * @return
     */
    @RequestMapping(value = {"/buildOrgnizationByUserId"},method = RequestMethod.GET)
    public WebResponseDto buildOrgnizationByUserId(){
        WebResponseDto responseDto = new WebResponseDto();
        DefaultBusinessContext ctx = DefaultBusinessContext.getContext();
        if(ctx.isStaff()){ // 员工
            JSONObject jsonObject = organizationBo.buildOrgnizationByUserId(ctx.getUser().getType(),ctx.getAccountId(),ctx.getAgentId(),ctx.getParentCompanyId(),ctx.getBranchCompanyId(),ctx.getProjectId());
            responseDto.setObj(jsonObject);
        }
        return responseDto;
    }
}
